package cn.com.guage.dtm.leetcode.hot100;

import java.util.ArrayList;
import java.util.List;

/**
 * 给定一个长度为 n 的整数数组 height 。有 n 条垂线，第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
 * 找出其中的两条线，使得它们与 x 轴共同构成的容器可以容纳最多的水。
 * 返回容器可以储存的最大水量。
 */
public class LeetCode_11_盛最多水的容器 {
    public static void main(String[] args) {
        int[] height1 = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        int[] height2 = {1, 1};
       // int max1 = maxArea(height1);
      //  int max2 = maxArea(height2);
       // System.out.println(max1);
       // System.out.println(max2);
        int max2 = maxArea2(height1);
        System.out.println(max2);
    }

    /**
     * 1. 50 / 65 个通过的测试用例
     * 2. 利用暴力破解法进行穷举计算面积，性能较差
     * @param height
     * @return
     */
    public static int maxArea(int[] height) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < height.length; i++) {
            for (int j = i + 1; j < height.length; j++) {
                int area = 0;
                int length = j - i;
                if (height[i] < height[j]) {
                    area = length * height[i];
                } else {
                    area = height[j] * length;
                }
                list.add(area);
            }
        }
        Integer max = list.stream().max(Integer::compareTo).orElse(null);
        if (max != null) {
            return max;
        } else {
            System.out.println("列表为空，没有最大值。");
        }
        return 0;
    }

    /**
     * 代码解释  : 利用双指针法
     * 1. 双指针初始化：left 指针初始化为数组的起始位置，right 指针初始化为数组的末尾位置。
     * 2. 最大水量初始化：maxWater 用于记录最大水量，初始值为 0。
     * 3. 循环条件：只要 left 小于 right，就继续循环。
     * 4. 计算当前水量：
     * 计算当前容器的宽度 width，即 right - left。
     * 计算当前容器的高度 currentHeight，取 height[left] 和 height[right] 中的较小值。
     * 计算当前水量 currentWater，即 width * currentHeight。
     * 更新 maxWater，取 maxWater 和 currentWater 中的较大值。
     * 5. 移动指针：
     * 如果 height[left] 小于 height[right]，则将 left 指针右移一位。
     * 否则，将 right 指针左移一位。
     * 6. 返回结果：循环结束后，返回 maxWater。
     * @param height
     * @return
     */
    public static int maxArea2(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int maxWater = 0;
        while (left < right) {
            int width = right - left;
            int currentHeight = Math.min(height[left], height[right]);
            int currentWater = width * currentHeight;
            maxWater = Math.max(maxWater, currentWater);

            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
        return maxWater;
    }
}
